﻿<%@ WebHandler Language="C#" Class="SyncServer.Upload" %>

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Data.Common;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using com.SyncConfiguration;
using System.Web.Script.Serialization;

namespace SyncServer
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Upload : IHttpHandler
    {

        const string TableSearchKey = "<t n=\"";
        SyncServer.Log log = null;
        SyncLogManager logmanger = new SyncLogManager();
        public void ProcessRequest(HttpContext context)
        {

            if ("1".Equals(System.Configuration.ConfigurationManager.AppSettings["EnabledMonitor"]))
                log = new SyncServer.Log();

            string token = context.Request[SyncServer.LoginConst.USERTOKEN];
           string version = context.Request[SyncServer.LoginConst.VERSION];
            string Host = context.Request.UserHostAddress;
            string requestkey = context.Request[SyncServer.LoginConst.RequestKey];
            string gzip = context.Request[SyncServer.LoginConst.EnableGZIP];
            bool EnableZip = gzip == null ? true : gzip == "1";
            HttpResponse response = context.Response;
            MemoryStream stream = new MemoryStream();
            MyWriter writer = new MyWriter(stream, EnableZip);

            response.ContentType = ("text/plain;charset=UTF8");
            response.Clear();
            if (log != null)
                log.Send(string.Format("{3}  远程主机：{0} , 用户名：{1} , 密码：*** , 版本：{2}", Host, token, version, DateTime.Now.ToString()));

            //验证RequestKey
            string requestKey = System.Configuration.ConfigurationManager.AppSettings["RequestKey"];
            String LocalKey = Jumpton.Common.Functions.EncryptString(token+ version + requestKey);
            if (!LocalKey.Equals(requestkey))
            {
                string err = "安全验证不匹配";
                //记录数据库日志
                logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, err, "", token, Environment.MachineName.ToString());
                writer.Write("error:"+err);
            }
            else
            {
                //验证版本是否正确
                Dictionary<string, SyncConfigurationSection> syncConfig = context.Cache["SyncConfiguration"] as Dictionary<string, SyncConfigurationSection>;
                SyncConfigurationSection config = syncConfig[version];

                if (config == null)
                {
                    if (log != null)
                        log.Send(string.Format("{1} 不存在的版本号\"{0}\"", version, DateTime.Now.ToString()));
                }
                else
                {
                    //首先对同步用户进行验证
                    bool LoginAuthorization = false;

                    //获取对象实例
                    System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(config.FullPath);
                    SyncInterface.IValidate instance = Activator.CreateInstance(assembly.GetType(config.Type.FullName)) as SyncInterface.IValidate;
                    LoginAuthorization = instance.Authorization(token);
                    //认证通过
                    if (LoginAuthorization)
                    {
                        System.Data.IDbTransaction tran = null;
                        try
                        {
                            //解压缩
                            String RequestContent = null;
                            //获取请求
                            byte[] requestData = new byte[context.Request.ContentLength];
                            int length = context.Request.InputStream.Read(requestData, 0, requestData.Length);
                            if (EnableZip)
                                requestData = CompressionHelper.DeCompress(requestData);
                            length = requestData.Length;
                            RequestContent = System.Text.Encoding.UTF8.GetString(requestData, 0, length);
                            if (instance.Connection != null && instance.Connection.State != ConnectionState.Open)
                            {
                                instance.Connection.Open();
                            }

                            tran = instance.Connection.BeginTransaction();
                            using (System.Data.IDbCommand insertCom = instance.Connection.CreateCommand())
                            {
                                System.Data.IDbCommand command = instance.Connection.CreateCommand();
                                command.Transaction = tran;//插入操作关联事务
                                int index = -1;
                                int start = 0;
                                while ((index = RequestContent.IndexOf("</t>", start)) != -1)
                                {
                                    string tableName = "";
                                    string str = RequestContent.Substring(start, index - start + 4);
                                    start = index + 4;
                                    //获取表名
                                    int tableNameStart = str.IndexOf(TableSearchKey) + TableSearchKey.Length;
                                    tableName = str.Substring(tableNameStart, str.IndexOf("\"", tableNameStart) - tableNameStart);
                                    int start2 = str.IndexOf("<k>");
                                    //主键
                                    string key = str.Substring(start2 + "<k>".Length);
                                    key = key.Substring(0, key.LastIndexOf("</k>"));
                                    start2 = str.IndexOf("<r>");
                                    string rows = str.Substring(start2, str.LastIndexOf("</r>") - start2 + 4);
                                    ///**上传数据**/
                                    int count = 0;//插入记录数
                                    int count2 = 0;//更新记录数
                                    //数据上传
                                    UploadData(instance, tableName, rows, command, key, ref count, ref count2);
                                    //记录日志
                                    if (log != null)
                                        log.Send(string.Format("{3} {0}表上传了{1}条数据,更新了{2}条数据", tableName, count, count2, DateTime.Now.ToString()));
                                }

                                //提交事务
                                tran.Commit();

                                stream = new MemoryStream();
                                writer = new MyWriter(stream, EnableZip);
                                writer.Write("true");
                            }
                        }
                        catch (System.Data.SqlClient.SqlException ex)
                        {
                            if (tran != null)
                                tran.Rollback();//事务回滚
                            //记录日志
                            if (log != null)
                                log.Send(string.Format("{3} 数据上传失败，事务已经回滚---→远程主机：{0} , 用户名：{1} , 密码：*** , 版本：{2}",
                            Host, token, version, DateTime.Now.ToString()));
                            if (log != null)
                            {
                                log.Send("错误内容:" + ex.StackTrace);
                                log.Send(ex.Source);
                                log.Send(ex.Errors.ToString());
                                log.Send(ex.Data.ToString());
                            }
                            stream = new MemoryStream();
                            writer = new MyWriter(stream, EnableZip);
                            writer.Write("error:" + ex.Message);
                        }
                        catch (Exception ex)
                        {
                            if (tran != null)
                                tran.Rollback();//事务回滚
                            //记录日志
                            if (log != null)
                                log.Send(string.Format("{3} 数据上传失败，事务已经回滚---→远程主机：{0} , 用户名：{1} , 密码：*** , 版本：{2}",
                            Host, token, version, DateTime.Now.ToString()));
                            if (log != null)
                            {
                                log.Send("错误内容:" + ex.Message.Replace("'", "''"));
                                log.Send("错误内容:" + ex.StackTrace.Replace("'", "''"));
                            }
                            stream = new MemoryStream();
                            writer = new MyWriter(stream, EnableZip);
                            writer.Write("error:" + ex.Message + ex.InnerException);
                        }
                    }
                    else
                    {
                        if (log != null)
                            log.Send(string.Format("{3} 登录失败(身份验证不通过)---→远程主机：{0} , 用户名：{1} , 密码：*** , 版本：{2}",
                                Host, token, version, DateTime.Now.ToString()));
                        //密码或者用户名不存在，暂时为了测试方便以“error:PasswordOrUserError”
                        writer.Write("error:PasswordOrUserError");
                        //writer.Write("z");
                    }
                }
               
            }

            writer.Flush();
            writer.Finish();
            if (stream.Length > 0)
            {
                stream.Position = 0;
                stream.WriteTo(response.OutputStream);
            }
            writer.Close();

            if (log != null)
                log.Close();
        }


        /// <summary>
        /// 属性，是否可以再利用
        /// </summary>
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// 上传数据
        /// </summary>
        internal void UploadData(SyncInterface.IValidate instance, string tableName, string rows, IDbCommand command, string key, ref int count, ref int count2)
        {
            DateTime value = DateTime.MinValue;
            if (rows.Length > 0)
            {
                int index2 = -1;
                int start3 = 0;

                if (tableName.StartsWith("UPLOAD_"))
                {
                    tableName = tableName.Substring("UPLOAD_".Length);
                }
                //2012071217002619223061|58|20120712000000129|1||/mnt/sdcard/jumpton/kpi/201207121659224091714.jpg|20120712165933||
                if (false)//(tableName == "CPR_DATA")
                {
                    while ((index2 = rows.IndexOf("</r>", start3)) != -1)
                    {
                        //获取行数据
                        string row = rows.Substring(start3 + 3, index2 - (start3 + 3));
                        if (log != null)
                            log.Send(row);
                        start3 = index2 + 4;
                        string[] valuesC = row.Split('|');
                        int i = 0;//执行结果影响行数
                        object o = null;
                        if (ExistData(command, tableName, key, valuesC[0]))
                        {
                            o = instance.GetSyncLogicSQL(tableName, SyncInterface.AccessTypeClass.AccessType.Update, 0);
                        }
                        else
                            o = instance.GetSyncLogicSQL(tableName, SyncInterface.AccessTypeClass.AccessType.Insert, 0);
                        if (o != null)
                        {
                            command.CommandText = o.ToString();

                            command.CommandText = command.CommandText.Replace("@TABLENAME", valuesC[valuesC.Length - 1]);
                        }
                        

                        //获取参数个数
                        int pcount = 0;
                        if (!string.IsNullOrEmpty(command.CommandText))
                        { pcount = command.CommandText.Split('@').Length - 1; }
                        else
                            return;

                        //先清空之前存在的参数
                        command.Parameters.Clear();

                        //创建命令参数
                        for (int j = 1; j <= pcount; j++)
                        {
                            System.Data.IDbDataParameter param = command.CreateParameter();
                            param.Value = DBNull.Value;
                            param.ParameterName = "@" + j.ToString();
                            command.Parameters.Add(param);

                        }

                        if (command.Parameters.Count != valuesC.Length-2)//后2列为id，服务器自增，和表名都不用插入
                        {
                            throw new Exception(string.Format("表{0}实际应该有{1}字段，但是提供了{2}个字段。", tableName, command.Parameters.Count, valuesC.Length));
                        }

                        if (!string.IsNullOrEmpty(command.CommandText))
                        {
                            for (int k = 0; k < command.Parameters.Count; k++)
                            {
                                IDbDataParameter paramU = (IDbDataParameter)command.Parameters[k];
                                paramU.DbType = DbType.String;
                                object objValue = System.DBNull.Value;

                                if (valuesC[k].Length == 0)
                                {
                                    paramU.Value = objValue;
                                }
                                else
                                {
                                    paramU.Value = valuesC[k];
                                }
                            }
                            i = command.ExecuteNonQuery();
                            count++;//更新数据行数
                        }
                        else
                            count2++;
                    }
                
                }
                else
                {
                    while ((index2 = rows.IndexOf("</r>", start3)) != -1)
                    {
                        //获取行数据
                        string row = rows.Substring(start3 + 3, index2 - (start3 + 3));
                        if (log != null)
                            log.Send(row);
                        start3 = index2 + 4;
                        string[] valuesC = row.Split('|');

                        int i = 0;//执行结果影响行数
                        object o = null;
                        if (ExistData(command, tableName, key, valuesC[0]))
                        {
                            o = instance.GetSyncLogicSQL(tableName, SyncInterface.AccessTypeClass.AccessType.Update, 0);
                        }
                        else
                            o = instance.GetSyncLogicSQL(tableName, SyncInterface.AccessTypeClass.AccessType.Insert, 0);
                        if (o != null)
                            command.CommandText = o.ToString();

                        //获取参数个数
                        int pcount = 0;
                        if (!string.IsNullOrEmpty(command.CommandText))
                        { pcount = command.CommandText.Split('@').Length - 1; }
                        else
                            return;


                        //先清空之前存在的参数
                        command.Parameters.Clear();


                        //创建命令参数
                        for (int j = 1; j <= pcount; j++)
                        {
                            System.Data.IDbDataParameter param = command.CreateParameter();
                            param.Value = DBNull.Value;
                            param.ParameterName = "@" + j.ToString();
                            command.Parameters.Add(param);

                        }

                        if (command.Parameters.Count>valuesC.Length)
                        {
                            throw new Exception(string.Format("表{0}实际应该有{1}字段，但是提供了{2}个字段。", tableName, command.Parameters.Count, valuesC.Length));
                        }

                        if (!string.IsNullOrEmpty(command.CommandText))
                        {
                            for (int k = 0; k < command.Parameters.Count; k++)
                            {
                                IDbDataParameter paramU = (IDbDataParameter)command.Parameters[k];
                                paramU.DbType = DbType.String;
                                object objValue = System.DBNull.Value;

                                if (valuesC[k].Length == 0)
                                {
                                    paramU.Value = objValue;
                                }
                                else
                                {
                                    paramU.Value = valuesC[k];
                                }
                            }
                            try
                            {
                                i = command.ExecuteNonQuery();
                            }
                            catch
                            {
                                throw;
                            }
                            count++;//更新数据行数
                        }
                        else
                            count2++;
                    }
                }

            }
        }

        public bool ExistData(IDbCommand com, string tablename, string key, string value)
        {
            bool flag = false;
            IDataReader reader = null;
            try
            {
                com.CommandText = " SELECT " + key + " FROM " + tablename + " WHERE " + key + "='" + value + "'";
                reader = com.ExecuteReader();
                if (reader.Read())
                {
                    flag = true;
                }
                else
                    flag = false;
            }
            catch
            {
                flag = false;
            }
            finally
            {
                if (reader != null)
                    reader.Close();
            }


            return flag;


        }

        public static string setJsonData(string tablename, bool success, string errmsg, bool end)
        {
            string jsonstring = "";
            System.Text.StringBuilder JsonString = new System.Text.StringBuilder();
            JsonString.Append("\"tablename\":\"{0}\",");//表名
            JsonString.Append("\"success\":\"{1}\",");//状态
            JsonString.Append("\"errmsg\":\"{2}\"");//错误信息
            jsonstring = string.Format(JsonString.ToString(), tablename, success, errmsg);
            if (!end)
                jsonstring = "{" + jsonstring + "},";
            else
                jsonstring = "[{" + jsonstring + "}]";
            return jsonstring;
        }
    }


}



       
        

        

